<?php

namespace App\Models;

use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Tymon\JWTAuth\Contracts\JWTSubject;
use Spatie\Permission\Traits\HasRoles;

/**
 * App\Models\User
 *
 * @property-read \Illuminate\Notifications\DatabaseNotificationCollection|\Illuminate\Notifications\DatabaseNotification[] $notifications
 * @property-read int|null $notifications_count
 * @property-write mixed $password
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\User newModelQuery()
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\User newQuery()
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\User query()
 * @mixin \Eloquent
 * @property int $id
 * @property string $name
 * @property string|null $email
 * @property \Illuminate\Support\Carbon|null $email_verified_at
 * @property string|null $last_token 上次登录token
 * @property string|null $remember_token
 * @property \Illuminate\Support\Carbon|null $created_at
 * @property \Illuminate\Support\Carbon|null $updated_at
 * @method static \Illuminate\Database\Eloquent\Builder|User whereCreatedAt($value)
 * @method static \Illuminate\Database\Eloquent\Builder|User whereEmail($value)
 * @method static \Illuminate\Database\Eloquent\Builder|User whereEmailVerifiedAt($value)
 * @method static \Illuminate\Database\Eloquent\Builder|User whereId($value)
 * @method static \Illuminate\Database\Eloquent\Builder|User whereLastToken($value)
 * @method static \Illuminate\Database\Eloquent\Builder|User whereName($value)
 * @method static \Illuminate\Database\Eloquent\Builder|User wherePassword($value)
 * @method static \Illuminate\Database\Eloquent\Builder|User whereRememberToken($value)
 * @method static \Illuminate\Database\Eloquent\Builder|User whereUpdatedAt($value)
 * @property int $uid
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\Permission[] $permissions
 * @property-read int|null $permissions_count
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\Role[] $roles
 * @property-read int|null $roles_count
 * @method static \Illuminate\Database\Eloquent\Builder|User permission($permissions)
 * @method static \Illuminate\Database\Eloquent\Builder|User role($roles, $guard = null)
 * @method static \Illuminate\Database\Eloquent\Builder|User whereUid($value)
 * @property string $nickname 昵称
 * @property int $status 状态:1正常0冻结
 * @property int $gender 性别:1男2女
 * @property string $avatar 头像
 * @property string $description 简介
 * @property-read \Illuminate\Database\Eloquent\Collection|User[] $customs
 * @property-read int|null $customs_count
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\Plan[] $owns
 * @property-read int|null $owns_count
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\Plan[] $plans
 * @property-read int|null $plans_count
 * @method static \Illuminate\Database\Eloquent\Builder|User whereAvatar($value)
 * @method static \Illuminate\Database\Eloquent\Builder|User whereDescription($value)
 * @method static \Illuminate\Database\Eloquent\Builder|User whereGender($value)
 * @method static \Illuminate\Database\Eloquent\Builder|User whereNickname($value)
 * @method static \Illuminate\Database\Eloquent\Builder|User whereStatus($value)
 */
class User extends Authenticatable implements JWTSubject
{
    use Notifiable, HasRoles;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password', 'nickname', 'avatar', 'description', 'gender', 'status', 'uid'
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
        'login_time' => 'datetime'
    ];

    protected $guard_name = 'api'; // 使用的守卫

    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

    public function getJWTCustomClaims(): array
    {
        return [];
    }

    public function avatar()
    {
        return $this->attributes['avatar'] ? url('storage/' . $this->attributes['avatar']) : url('images/avatar/default.jpg');
    }

    public function isAdmin()
    {
        return $this->hasRole('admin');
    }

    /**
     * 是否是摄影师或模特
     * @return bool
     */
    public function isPhotographer()
    {
        return $this->hasRole('photographer') || $this->hasRole('model');
    }

    /**
     * 是否冻结
     * @return bool
     */
    public function isLocked()
    {
        return $this->status === 0;
    }

    /**
     * 拥有的拍摄
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function owns()
    {
        return $this->hasMany(Plan::class);
    }

    /**
     * 可见的拍摄 (包含分享给我的)
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function plans()
    {
        return $this->belongsToMany(Plan::class);
    }

    /**
     * 我添加的用户
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function customs()
    {
        return $this->hasMany(User::class, 'uid', 'id');
    }

    /**
     * 用户登录日志
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function logs(): \Illuminate\Database\Eloquent\Relations\HasMany
    {
        return $this->hasMany(Log::class);
    }

    /**
     * 用户菜单
     * @return Menu[]|\Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Query\Builder[]|\Illuminate\Support\Collection
     */
    public function getMenus()
    {
        $menuIds = $this->roles->first()->menus()->pluck('menus.id')->toArray();
        $menuIds = Menu::whereIn('id', $menuIds)->pluck('pid', 'id')->toArray();
        $menuIds = array_merge(array_filter(array_values($menuIds)), array_keys($menuIds));

        return Menu::with(['children' => function ($query) use ($menuIds) {
            $query->whereIn('id', $menuIds);
        }])->whereIn('id', $menuIds)->where('pid', 0)->get();
    }
}
